// ============================================
// 15 - 输入/输出 (I/O)
// ============================================

/// Rust 的 I/O 功能主要在 std::io 模块中

use std::io::{self, Read, Write, BufRead, BufReader, BufWriter};
use std::fs::{self, File, OpenOptions};
use std::path::Path;

// ==================== 标准输入输出 ====================

/// 读取标准输入
pub fn reading_stdin() {
    println!("\n=== 读取标准输入 ===");
    
    println!("示例: 读取一行输入");
    println!("let mut input = String::new();");
    println!("io::stdin().read_line(&mut input).expect(\"读取失败\");");
}

pub fn read_user_input() -> String {
    let mut input = String::new();
    io::stdin()
        .read_line(&mut input)
        .expect("读取输入失败");
    input.trim().to_string()
}

/// 写入标准输出
pub fn writing_stdout() {
    println!("\n=== 写入标准输出 ===");
    
    // println! 宏
    println!("使用 println! 宏");
    
    // print! 宏
    print!("使用 print! 宏（不换行）");
    println!();
    
    // 使用 stdout
    let mut stdout = io::stdout();
    stdout.write_all("使用 stdout 写入\n".as_bytes()).unwrap();
    stdout.flush().unwrap();
}

/// 标准错误输出
pub fn writing_stderr() {
    println!("\n=== 标准错误输出 ===");
    
    // eprintln! 宏
    eprintln!("这是错误消息");
    
    // 使用 stderr
    let mut stderr = io::stderr();
    stderr.write_all("使用 stderr 写入错误\n".as_bytes()).unwrap();
}

// ==================== 文件操作 ====================

/// 读取文件
pub fn reading_files() {
    println!("\n=== 读取文件 ===");
    
    // 方法1: 读取整个文件到字符串
    match fs::read_to_string("example.txt") {
        Ok(contents) => println!("文件内容: {}", contents),
        Err(e) => println!("读取文件失败: {}", e),
    }
    
    // 方法2: 读取为字节
    match fs::read("example.txt") {
        Ok(bytes) => println!("读取了 {} 字节", bytes.len()),
        Err(e) => println!("读取文件失败: {}", e),
    }
    
    // 方法3: 使用 File 和 Read trait
    if let Ok(mut file) = File::open("example.txt") {
        let mut contents = String::new();
        match file.read_to_string(&mut contents) {
            Ok(size) => println!("读取了 {} 字节", size),
            Err(e) => println!("读取失败: {}", e),
        }
    }
}

/// 写入文件
pub fn writing_files() {
    println!("\n=== 写入文件 ===");
    
    // 方法1: 写入字符串
    let content = "Hello, Rust I/O!\n";
    match fs::write("output.txt", content) {
        Ok(_) => println!("写入成功"),
        Err(e) => println!("写入失败: {}", e),
    }
    
    // 方法2: 使用 File 和 Write trait
    match File::create("output2.txt") {
        Ok(mut file) => {
            if let Err(e) = file.write_all("Hello from File!\n".as_bytes()) {
                println!("写入失败: {}", e);
            } else {
                println!("写入成功");
            }
        }
        Err(e) => println!("创建文件失败: {}", e),
    }
}

/// 追加到文件
pub fn appending_to_files() {
    println!("\n=== 追加到文件 ===");
    
    match OpenOptions::new()
        .write(true)
        .append(true)
        .create(true)
        .open("append.txt")
    {
        Ok(mut file) => {
            if let Err(e) = writeln!(file, "追加的一行") {
                println!("追加失败: {}", e);
            } else {
                println!("追加成功");
            }
        }
        Err(e) => println!("打开文件失败: {}", e),
    }
}

// ==================== 缓冲 I/O ====================

/// 缓冲读取
pub fn buffered_reading() {
    println!("\n=== 缓冲读取 ===");
    
    if let Ok(file) = File::open("example.txt") {
        let reader = BufReader::new(file);
        
        println!("逐行读取:");
        for (i, line) in reader.lines().enumerate() {
            match line {
                Ok(content) => println!("第 {} 行: {}", i + 1, content),
                Err(e) => println!("读取行失败: {}", e),
            }
        }
    }
}

/// 缓冲写入
pub fn buffered_writing() {
    println!("\n=== 缓冲写入 ===");
    
    match File::create("buffered_output.txt") {
        Ok(file) => {
            let mut writer = BufWriter::new(file);
            
            for i in 0..5 {
                if let Err(e) = writeln!(writer, "行 {}", i) {
                    println!("写入失败: {}", e);
                    return;
                }
            }
            
            // 刷新缓冲区
            if let Err(e) = writer.flush() {
                println!("刷新失败: {}", e);
            } else {
                println!("缓冲写入成功");
            }
        }
        Err(e) => println!("创建文件失败: {}", e),
    }
}

// ==================== 文件系统操作 ====================

/// 文件和目录操作
pub fn filesystem_operations() {
    println!("\n=== 文件系统操作 ===");
    
    // 检查文件是否存在
    if Path::new("example.txt").exists() {
        println!("文件存在");
    }
    
    // 创建目录
    if let Err(e) = fs::create_dir_all("test_dir/sub_dir") {
        println!("创建目录失败: {}", e);
    } else {
        println!("目录创建成功");
    }
    
    // 读取目录
    if let Ok(entries) = fs::read_dir(".") {
        println!("\n当前目录内容:");
        for entry in entries.flatten() {
            println!("  {:?}", entry.file_name());
        }
    }
    
    // 重命名文件
    if Path::new("output.txt").exists() {
        if let Err(e) = fs::rename("output.txt", "renamed.txt") {
            println!("重命名失败: {}", e);
        }
    }
    
    // 删除文件
    if Path::new("temp.txt").exists() {
        if let Err(e) = fs::remove_file("temp.txt") {
            println!("删除文件失败: {}", e);
        }
    }
    
    // 删除目录
    if Path::new("test_dir").exists() {
        if let Err(e) = fs::remove_dir_all("test_dir") {
            println!("删除目录失败: {}", e);
        }
    }
}

/// 文件元数据
pub fn file_metadata() {
    println!("\n=== 文件元数据 ===");
    
    if let Ok(metadata) = fs::metadata("example.txt") {
        println!("文件大小: {} 字节", metadata.len());
        println!("是否为文件: {}", metadata.is_file());
        println!("是否为目录: {}", metadata.is_dir());
        println!("是否只读: {}", metadata.permissions().readonly());
        
        if let Ok(modified) = metadata.modified() {
            println!("最后修改时间: {:?}", modified);
        }
    }
}

// ==================== 路径操作 ====================

/// 路径处理
pub fn path_operations() {
    println!("\n=== 路径操作 ===");
    
    let path = Path::new("dir/file.txt");
    
    println!("完整路径: {:?}", path);
    println!("文件名: {:?}", path.file_name());
    println!("扩展名: {:?}", path.extension());
    println!("父目录: {:?}", path.parent());
    
    // 构建路径
    let mut path_buf = std::path::PathBuf::from("dir");
    path_buf.push("subdir");
    path_buf.push("file.txt");
    println!("构建的路径: {:?}", path_buf);
    
    // 规范化路径
    if let Ok(canonical) = path_buf.canonicalize() {
        println!("规范路径: {:?}", canonical);
    }
}

// ==================== 临时文件 ====================

/// 临时文件（需要 tempfile crate）
pub fn temp_files() {
    println!("\n=== 临时文件 ===");
    println!("使用 tempfile crate 创建临时文件");
    println!("临时文件在离开作用域时自动删除");
}

// ==================== 命令行参数 ====================

/// 读取命令行参数
pub fn command_line_args() {
    println!("\n=== 命令行参数 ===");
    
    let args: Vec<String> = std::env::args().collect();
    println!("程序名: {}", args[0]);
    
    if args.len() > 1 {
        println!("参数:");
        for (i, arg) in args.iter().skip(1).enumerate() {
            println!("  参数 {}: {}", i + 1, arg);
        }
    } else {
        println!("没有提供参数");
    }
}

/// 环境变量
pub fn environment_variables() {
    println!("\n=== 环境变量 ===");
    
    // 读取环境变量
    match std::env::var("HOME") {
        Ok(home) => println!("HOME: {}", home),
        Err(e) => println!("读取 HOME 失败: {}", e),
    }
    
    // 设置环境变量
    unsafe {
        std::env::set_var("MY_VAR", "my_value");
    }
    if let Ok(value) = std::env::var("MY_VAR") {
        println!("MY_VAR: {}", value);
    }
    
    // 列出所有环境变量
    println!("\n所有环境变量 (前5个):");
    for (i, (key, value)) in std::env::vars().take(5).enumerate() {
        println!("  {}: {} = {}", i + 1, key, value);
    }
}

// ==================== 实际应用示例 ====================

/// 配置文件读取
pub fn read_config_file() {
    println!("\n=== 读取配置文件 ===");
    
    let config_content = r#"
# 配置文件示例
name=MyApp
version=1.0.0
debug=true
"#;
    
    // 写入配置文件
    if let Err(e) = fs::write("config.txt", config_content) {
        println!("写入配置失败: {}", e);
        return;
    }
    
    // 读取并解析配置
    match fs::read_to_string("config.txt") {
        Ok(content) => {
            println!("配置内容:");
            for line in content.lines() {
                let line = line.trim();
                if !line.is_empty() && !line.starts_with('#') {
                    println!("  {}", line);
                }
            }
        }
        Err(e) => println!("读取配置失败: {}", e),
    }
}

/// 日志文件写入
pub fn logging_to_file() {
    println!("\n=== 日志文件 ===");
    
    let log_entry = format!(
        "[{}] 应用启动\n",
        chrono::Local::now().format("%Y-%m-%d %H:%M:%S")
    );
    
    match OpenOptions::new()
        .create(true)
        .append(true)
        .open("app.log")
    {
        Ok(mut file) => {
            if let Err(e) = file.write_all(log_entry.as_bytes()) {
                println!("写入日志失败: {}", e);
            } else {
                println!("日志写入成功");
            }
        }
        Err(e) => println!("打开日志文件失败: {}", e),
    }
}

// 注意: chrono 是一个外部 crate，这里为了演示目的使用
// 如果没有 chrono，可以使用简单的时间戳
mod chrono {
    pub struct Local;
    impl Local {
        pub fn now() -> DateTime {
            DateTime
        }
    }
    
    pub struct DateTime;
    impl DateTime {
        pub fn format(&self, _fmt: &str) -> String {
            "2025-01-01 00:00:00".to_string()
        }
    }
}

/// CSV 文件处理
pub fn csv_processing() {
    println!("\n=== CSV 文件处理 ===");
    
    let csv_content = "姓名,年龄,城市\n张三,25,北京\n李四,30,上海\n";
    
    if let Err(e) = fs::write("data.csv", csv_content) {
        println!("写入 CSV 失败: {}", e);
        return;
    }
    
    if let Ok(content) = fs::read_to_string("data.csv") {
        println!("CSV 数据:");
        for line in content.lines() {
            let fields: Vec<&str> = line.split(',').collect();
            println!("  {:?}", fields);
        }
    }
}

// ==================== I/O 最佳实践 ====================

/// I/O 最佳实践
pub fn io_best_practices() {
    println!("\n=== I/O 最佳实践 ===");
    
    println!("1. 始终处理错误");
    println!("2. 使用缓冲 I/O 提高性能");
    println!("3. 及时关闭文件（Rust 自动处理）");
    println!("4. 对大文件使用流式处理");
    println!("5. 使用 Path 和 PathBuf 处理路径");
    println!("6. 考虑使用异步 I/O 处理大量操作");
    println!("7. 使用合适的编码处理文本");
}

/// 主函数 - 演示所有功能
#[allow(dead_code)]
pub fn main() {
    println!("╔════════════════════════════════════════╗");
    println!("║   Rust I/O 教程                        ║");
    println!("╚════════════════════════════════════════╝");
    
    reading_stdin();
    writing_stdout();
    writing_stderr();
    reading_files();
    writing_files();
    appending_to_files();
    buffered_reading();
    buffered_writing();
    filesystem_operations();
    file_metadata();
    path_operations();
    temp_files();
    command_line_args();
    environment_variables();
    read_config_file();
    logging_to_file();
    csv_processing();
    io_best_practices();
    
    println!("\n✅ I/O 教程完成！");
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_file_operations() {
        // 写入文件
        let content = "测试内容";
        fs::write("test_file.txt", content).unwrap();
        
        // 读取文件
        let read_content = fs::read_to_string("test_file.txt").unwrap();
        assert_eq!(content, read_content);
        
        // 清理
        fs::remove_file("test_file.txt").unwrap();
    }
    
    #[test]
    fn test_path_operations() {
        let path = Path::new("dir/file.txt");
        assert_eq!(path.file_name().unwrap(), "file.txt");
        assert_eq!(path.extension().unwrap(), "txt");
    }
}

